package com.zzzzzz.plugins.jdbctemplate;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.SingleColumnRowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Service;

import com.zzzzzz.oms.orderHead.OrderHead;

@Service
public class BaseDao {
	@Resource
	public NamedParameterJdbcTemplate jt;
	
	public <T> long updateGetLongKey(final String sql, T t){
		SqlParameterSource param = new BeanPropertySqlParameterSource(t);
	    KeyHolder keyHolder = new GeneratedKeyHolder();  
	    jt.update(sql, param, keyHolder);
	    return keyHolder.getKey().longValue();
	}
	
	public <T> int updateGetIntKey(final String sql,T t){
		SqlParameterSource param = new BeanPropertySqlParameterSource(t);
	    KeyHolder keyHolder = new GeneratedKeyHolder();  
	    jt.update(sql, param, keyHolder);
	    return keyHolder.getKey().intValue();
	}
	
	public <T> int update(final String sql, T t){
		SqlParameterSource param = new BeanPropertySqlParameterSource(t);
	    return jt.update(sql, param);
	}
	
	public <T> int update(Finder finder){
	    return jt.update(finder.getSql(), finder.getParams());
	}
	
	public <T> int[] batchUpdate(final String sql, List<T> t){
		SqlParameterSource[] batchParams = SqlParameterSourceUtils.createBatch(t.toArray());
	    return jt.batchUpdate(sql, batchParams);
	}
	
	public Long findLong(Finder finder){
		return jt.queryForObject(finder.getSql(), finder.getParams(), Long.class);
	}
	
	public Integer findInt(Finder finder){
		return jt.queryForObject(finder.getSql(), finder.getParams(), Integer.class);
	}
	public String findString(Finder finder){
		return jt.queryForObject(finder.getSql(), finder.getParams(), String.class);
	}
	
	public <T> T findOne(Finder finder, Class<T> mappedClass){
		return jt.queryForObject(finder.getSql(), finder.getParams(), new BeanPropertyRowMapper<T>(mappedClass));
	}
	public <T> T findOneOrNull(Finder finder, Class<T> mappedClass){
		try{
			return this.findOne(finder, mappedClass);
		}catch(IncorrectResultSizeDataAccessException e){
			return null;
		}
	}
	
	public Map<String, Object> findOne(Finder finder){
		return jt.queryForMap(finder.getSql(), finder.getParams());
	}
	
	public <T> List<T> findList(Finder finder, Class<T> mappedClass) {
		return jt.query(finder.getSql(), finder.getParams(), new BeanPropertyRowMapper<T>(mappedClass));
	}
	
	public <T> List<T> findListSingleColumn(Finder finder, Class<T> mappedClass) {
		return jt.query(finder.getSql(), finder.getParams(), new SingleColumnRowMapper<T>(mappedClass));
	}
	
	public List<Map<String, Object>> findList(Finder finder) {
		return jt.queryForList(finder.getSql(), finder.getParams());
	}
}
